package com.yanqu.road.server.manager.match;

import com.yanqu.road.entity.match.MatchData;
import com.yanqu.road.entity.match.UserMatchData;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.logic.bussiness.match.MatchBussiness;
import com.yanqu.road.logic.bussiness.rank.RankBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.variety.VarietyProto;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.manager.banquet.CrossPartyMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author ：zfr
 * @date ：2021/2/4 10:15
 * 赛事
 */
public class CrossMatchMgr extends TempMgr {
    private static Logger logger = LogManager.getLogger(CrossMatchMgr.class.getName());
    private static Map<Long, GroupMatch> groupMatchMap; //分组赛事 groupId - groupMatch
    private static List<MatchData> matchDataList; //赛事集合
//    private static Map<Integer, Map<Long, Map<Long, RankRemoveData>>> rankRemoveDataMap;
    /**
     * 赛事玩家数据集合Map (groupId-timeId-id-list)
     */
    private static Map<Long, Map<Integer, Map<Integer, List<UserMatchData>>>> userDataListMap;
    /**
     * 奖励留存天数
     */
    private static final int rewardSaveDays = 30;
    /**
     * 最大Id
     */
    private static AtomicInteger nextId = new AtomicInteger(1);
    /**
     * 周排行
     * groupId-weekId-rankList
     */
    private static Map<Long, Map<Integer, LinkedList<CrossUserRank>>> crossMatchWeekRankMap;

    /**
     * 获取杂艺排行
     * @param id
     * @param serverId
     * @param playerId
     * @param respMsg
     */
    public static void getVarietyRank(int id, long serverId, long playerId, VarietyProto.GetVarietyRankRespMsg.Builder respMsg) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch != null) {
            groupMatch.getVarietyRank(id, serverId, playerId, respMsg);
        }
    }

    /**
     * 红点同步
     * @param serverId
     * @param playerId
     * @param respMsg
     */
    public static void syncRedPot(long serverId, long playerId, VarietyProto.VarietyRedPot.Builder respMsg) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch != null) {
            groupMatch.syncRedPot(serverId, playerId, respMsg);
            return;
        }
        //如果是划分到了其他区服分组 领奖需要遍历所有分组领奖
        for (GroupMatch groupMatchTemp : groupMatchMap.values()) {
            groupMatchTemp.syncRedPot(serverId, playerId, respMsg);
        }
    }

    /**
     * 同步门客赚钱
     * @param serverId
     * @param playerId
     * @param syncPatronsTempList
     */
    public static void syncPatronsAbility(long serverId, long playerId, List<VarietyProto.SyncPatronsTemp> syncPatronsTempList) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch != null) {
            groupMatch.syncPatronsAbility(serverId, playerId, syncPatronsTempList);
        }
    }

    @Override
    public boolean reloadData() throws Exception {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -rewardSaveDays);
        int timeId = parseTimeId(cal.getTimeInMillis());
        matchDataList = MatchBussiness.getMatchDataList(timeId);
        userDataListMap = MatchBussiness.getUserDataList(timeId);
        nextId = new AtomicInteger(MatchBussiness.getMatchMaxId() + 1);
        Calendar now = Calendar.getInstance();
        int thisWeekId = getThisWeekId(now);
        now.add(Calendar.DATE, -7);
        int preWeekId = parseTimeId(now.getTimeInMillis());
        crossMatchWeekRankMap = RankBussiness.getCrossMatchWeekRankMap(preWeekId, thisWeekId);
        initGroupMatchMap();
//        rankRemoveDataMap = MatchBussiness.getRankRemoveDataMap(thisWeekId);
        return true;
    }

    //时间格式YyyyMmDd
    public static int parseTimeId(long time) {
        return Integer.valueOf(DateHelper.getPyyyyMMddDateString(time / 1000));
    }

    /**
     * 读库初始化 groupMatchMap
     */
    private void initGroupMatchMap() {
        synchronized (groupMatchMap) {
            for (MatchData data : matchDataList) {
                if (!groupMatchMap.containsKey(data.getGroupId())) {
                    groupMatchMap.put(data.getGroupId(), new GroupMatch(data.getGroupId(), new ConcurrentHashMap<>(), new ConcurrentHashMap<>()));
                }
                groupMatchMap.get(data.getGroupId()).initMatchMap(data, userDataListMap.get(data.getGroupId()), crossMatchWeekRankMap.get(data.getGroupId()));
            }
        }
    }

    @Override
    public boolean init() throws Exception {
        groupMatchMap = new ConcurrentHashMap<>();
//        addServerGroupReloadListener();
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        for (GroupMatch groupMatch : groupMatchMap.values()) {
            groupMatch.save();
        }

//        for (Map<Long, Map<Long, RankRemoveData>> weekMap : rankRemoveDataMap.values()) {
//            for (Map<Long, RankRemoveData> serverMap : weekMap.values()) {
//                for (RankRemoveData data : serverMap.values()) {
//                    if (data.isInsertOption()) {
//                        MatchBussiness.addRankRemoveData(data);
//                    } else if (data.isUpdateOption()) {
//                        MatchBussiness.updateRankRemoveData(data);
//                    }
//                }
//            }
//        }
        return true;
    }

    /**
     * 检查赛事初始化
     * @param groupIdList
     */
    public static void checkMatchInit(List<Long> groupIdList) {
        new CrossPartyMgr().saveRelationData();
        logger.info("saveRelationData");
        synchronized (groupMatchMap) {
            for (Long groupId : groupIdList) {
                if (!groupMatchMap.containsKey(groupId)) {
                    groupMatchMap.put(groupId, new GroupMatch(groupId, new ConcurrentHashMap<>(), new ConcurrentHashMap<>()));
                }
                groupMatchMap.get(groupId).checkMatchInit();
            }
        }
    }

    /**
     * 同步杂艺列表给客户端
     * @param playerId  玩家id
     * @param serverId  区服id
     */
    public static void syncVarietyList(long playerId, long serverId) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch != null) {
            groupMatch.syncVarietyList(playerId, serverId);
        }
    }

    /**
     * 获取分组赛事
     * @param serverId
     * @return
     */
    public static GroupMatch getGroupMatch(long serverId) {
//        //查看区服分组是否开启杂艺
//        MatchServerGroup serverGroup = MatchServerGroupMgr.getServerGroupByServerId(serverId);
//        if (serverGroup == null || serverGroup.getMatchState() == 0) {
//            return null;
//        }
//       return groupMatchMap.get(serverGroup.getGroupId());
        return groupMatchMap.get(serverId);
    }

    /**
     * 同步玩家杂艺派遣队伍
     * @param playerId 玩家id
     * @param serverId 区服id
     */
    public static void syncTeamList(long playerId, long serverId) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch != null) {
            groupMatch.syncTeamList(playerId, serverId);
        }
    }

    /**
     * 派遣队伍
     * @param serverId 区服id
     * @param playerId 玩家id
     * @param msg   请求协议内容
     * @param respMsg 返回协议内容
     */
    public static void dispatchTeam(long serverId, long playerId, VarietyProto.DispatchTeamCrossReqMsg msg, VarietyProto.DispatchTeamCrossRespMsg.Builder respMsg) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch == null) {
            respMsg.setRet(GameErrorCode.E_VARIETY_SERVER_GROUP_NOT_OPEN);
            return;
        }
        groupMatch.dispatchTeam(serverId, playerId, msg, respMsg);
    }

    /**
     * 请求发奖
     * @param serverId           区服id
     * @param playerId           玩家id
     * @param getRewardDataList  派遣时间
     * @param respMsg
     */
    public static void getReward(long serverId, long playerId, List<VarietyProto.GetRewardData> getRewardDataList, VarietyProto.GetRewardCrossRespMsg.Builder respMsg) {
//        GroupMatch groupMatch = getGroupMatch(serverId);
//        if (groupMatch == null) {
//            return;
//        }
        for (GroupMatch groupMatch : groupMatchMap.values()) {
            groupMatch.getReward(serverId, playerId, getRewardDataList, respMsg);
        }
    }

    //分组变更造成的杂艺提前结束
//    private void addServerGroupReloadListener(){
//        MatchServerGroupMgr.addReloadListener(new ManagerReloadListener() {
//            @Override
//            public void notifyReload() {
//                serverGroupReload();
//                long zeroTime = DateHelper.getTodayZeroTimeStamp();
//                long nowTime = System.currentTimeMillis();
//                //还未到杂艺开启时间 分组区服变动不提前结束
//                if (nowTime >= (zeroTime + GameConfig.VARIETY_BEGIN_TIME * 60 * 1000)) {
//                    for (GroupMatch groupMatch : groupMatchMap.values()) {
//                        groupMatch.overForGroupChange();
//                    }
//                }
//                notifyServerReload();
//            }
//        });
//    }

//    public void notifyServerReload() {
//        List<ServerInfo> serverInfoList = ServerListMgr.getOpenServerList();
//        int channelId = ConfigHelper.getInt("channelId");
//        CommonProto.NullValueMsg.Builder msg = CommonProto.NullValueMsg.newBuilder();
//        YanQuMessage message = YanQuMessageUtils.buildMessage(GameProtocol.S_VARIETY_SYNC_GROUP_SERVER_LIST, msg);
//        for (ServerInfo serverInfo : serverInfoList) {
//            if(serverInfo.getChannelId() == channelId){
//                MessageHelper.sendChannelPacket(serverInfo.getServerId(), 0, message);
//            }
//        }
//    }



    /**
     * 同步杂艺详细数据
     * @param msg
     * @param respMsg
     */
    public static void syncVarietyDetailData(long serverId, VarietyProto.SyncVarietyDetailReqMsg msg, VarietyProto.SyncVarietyDetailRespMsg.Builder respMsg) {
        GroupMatch groupMatch = getGroupMatch(serverId);
        if (groupMatch == null) {
            return;
        }
        groupMatch.syncVarietyDetailData(msg, respMsg);
    }

    public static int getNextId() {
        return nextId.getAndIncrement();
    }

    //获取所在组的区服列表
//    public static Set<Long> getGroupServer(int groupId){
//        Set<Long> serverSet = new HashSet<>();
//        MatchServerGroup serverGroup = MatchServerGroupMgr.getServerGroupMap().get(groupId);
//        if (serverGroup != null && serverGroup.getMatchState() != 0) {
//            serverSet.addAll(serverGroup.getServerList());
//        }
//        return serverSet;
//    }

    private static boolean checkIsLastRewardTime() {
        long zeroTime = DateHelper.getTodayZeroTimeStamp();
        long nowTime = System.currentTimeMillis();
        return nowTime >= (zeroTime + GameConfig.VARIETY_END_TIME * 60 * 1000);
    }

    //本周id
    public static int getThisWeekId(Calendar now){
        boolean isNextWeek = false;
        if (now.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY && checkIsLastRewardTime()) {
            isNextWeek = true;
        }
        Date monday = DateHelper.getThisWeekMonday(now.getTime());
        now.setTime(monday);
        if (isNextWeek) {
            now.add(Calendar.DATE, 7);
        }
        return parseTimeId(now.getTimeInMillis());
    }

    /**
     * 区服重载,排行榜重新分组
     */
//    public static void serverGroupReload() {
//        Calendar now = Calendar.getInstance();
//        int thisWeekId = getThisWeekId(now);
//        synchronized (groupMatchMap) {
//            LinkedList<CrossUserRank> crossUserRanks = new LinkedList<>();
//            for (GroupMatch groupMatch : groupMatchMap.values()) {
//                Set<Long> serverIdSet = getGroupServer(groupMatch.getGroupId());
//                if (groupMatch.getRankModelMap().containsKey(thisWeekId)) {
//                    MatchWeekRankModel matchWeekRankModel = groupMatch.getRankModelMap().get(thisWeekId);
//                    crossUserRanks.addAll(matchWeekRankModel.removeRank(serverIdSet));
//                }
//            }
//            //上面移除的重新排
//            Iterator<CrossUserRank> iterator = crossUserRanks.iterator();
//            while (iterator.hasNext()) {
//                CrossUserRank rank = iterator.next();
//                int groupId = getGroupId(rank.getUserBaseInfo().getServerId());
//                if (groupMatchMap.containsKey(groupId)) {
//                    groupMatchMap.get(groupId).changeUserRank(thisWeekId, rank);
//                    iterator.remove();
//                }
//            }
//            //加载一遍移除的数据
//            Map<Long, Map<Long, RankRemoveData>> weekMap = rankRemoveDataMap.get(thisWeekId);
//            if (weekMap != null) {
//                for (Map.Entry<Long, Map<Long, RankRemoveData>> mapEntry : weekMap.entrySet()) {
//                    int groupId = getGroupId(mapEntry.getKey());
//                    if (groupMatchMap.containsKey(groupId)) {
//                        for (RankRemoveData data : mapEntry.getValue().values()) {
//                            if (data.getValue() > 0) {
//                                CrossUserRank crossUserRank = new CrossUserRank();
//                                crossUserRank.setUserId(data.getUserId());
//                                crossUserRank.setUserBaseInfo(data.getUserBaseInfo());
//                                crossUserRank.setValue(BigInteger.valueOf(data.getValue()));
//                                groupMatchMap.get(groupId).changeUserRank(thisWeekId, crossUserRank);
//                                data.setValue(0L);
//                            }
//                        }
//                    }
//                }
//            }
//            //转存被移除的排行榜数据
//            if (crossUserRanks.size() > 0) {
//                addRemoveData(thisWeekId, crossUserRanks);
//            }
//        }
//    }

    /**
     * 新增区服变动被移除的排行数据
     * @param thisWeekId
     * @param crossUserRanks
     */
//    public static void addRemoveData(int thisWeekId, LinkedList<CrossUserRank> crossUserRanks) {
//        synchronized (rankRemoveDataMap) {
//            for (CrossUserRank crossUserRank : crossUserRanks) {
//                if (!rankRemoveDataMap.containsKey(thisWeekId)) {
//                    rankRemoveDataMap.put(thisWeekId, new ConcurrentHashMap<>());
//                }
//                if (!rankRemoveDataMap.get(thisWeekId).containsKey(crossUserRank.getUserBaseInfo().getServerId())) {
//                    rankRemoveDataMap.get(thisWeekId).put(crossUserRank.getUserBaseInfo().getServerId(), new ConcurrentHashMap<>());
//                }
//                if (!rankRemoveDataMap.get(thisWeekId).get(crossUserRank.getUserBaseInfo().getServerId()).containsKey(crossUserRank.getUserId())) {
//                    RankRemoveData data = new RankRemoveData();
//                    data.setWeekId(thisWeekId);
//                    data.setServerId(crossUserRank.getUserBaseInfo().getServerId());
//                    data.setUserId(crossUserRank.getUserId());
//                    data.setInsertOption();
//                    rankRemoveDataMap.get(thisWeekId).get(crossUserRank.getUserBaseInfo().getServerId()).put(crossUserRank.getUserId(), data);
//                }
//                RankRemoveData data = rankRemoveDataMap.get(thisWeekId).get(crossUserRank.getUserBaseInfo().getServerId()).get(crossUserRank.getUserId());
//                data.setUserBaseInfo(crossUserRank.getUserBaseInfo());
//                data.setValue(crossUserRank.getValue().longValue());
//            }
//        }
//    }

//    public static int getGroupId(long serverId) {
//        MatchServerGroup serverGroup = MatchServerGroupMgr.getServerGroupByServerId(serverId);
//        if(serverGroup != null && serverGroup.getMatchState() == 1){
//            return serverGroup.getGroupId();
//        }
//        return 0;
//    }

    /**
     * 通知排行榜变更
     * @param groupId
     * @param weekId
     * @param crossUserRank
     */
    public static void changeUserRank(long groupId, int weekId, CrossUserRank crossUserRank) {
        GroupMatch groupMatch = groupMatchMap.get(groupId);
        if (groupMatch != null) {
            groupMatch.changeUserRank(weekId, crossUserRank);
        }
    }

    public static MatchWeekRankModel getRankListModel(long groupId, int weekId) {
        GroupMatch groupMatch = groupMatchMap.get(groupId);
        if (groupMatch != null) {
            return groupMatch.getRankListModel(weekId);
        }
        return null;
    }

    //移除过期数据
    public static void removeOutTimeData(){
        Calendar now = Calendar.getInstance();
        now.add(Calendar.MONTH, -1);
        int monthBefore = parseTimeId(now.getTimeInMillis());
        for (GroupMatch groupMatch : groupMatchMap.values()) {
            groupMatch.removeOutTimeData(monthBefore);
        }
//        for (Integer weekId : rankRemoveDataMap.keySet()) {
//            if (weekId < monthBefore) {
//                rankRemoveDataMap.remove(weekId);
//            }
//        }
    }
}
